package com.android.support.lib.universal.sdk.weixin.base;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.android.support.lib.universal.http.NotifyUrl;
import com.android.support.lib.universal.listenner.QrBaseCallBack;
import com.android.support.lib.universal.sdk.weixin.wxapi.ParamUtil;
import com.android.support.lib.universal.sdk.weixin.wxapi.Util;
import com.android.support.lib.universal.sdk.weixin.wxapi.WeixinManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;

/**
 * 微信扫码支付(新接口才支持),直接实例化后，调用onPay(),onCancel()即可。
 * 
 * @author 彭治铭
 *
 */
public class CodeWXPayEntry {

	private Context context;

	private ParamUtil paramUtil = new ParamUtil();// 微信参数
	private QrBaseCallBack mQrBaseCallBack;// 回调函数

	private String code_url;// 二维码链接
	private Bitmap bitmap;// 二维码位图
	private Boolean isCancel = false;// 轮询是否取消

	private static enum LocalRetCode {// 自定义常量
		ERR_OK, ERR_HTTP, ERR_JSON, ERR_OTHER
	}

	/**
	 * 扫码支付
	 * 
	 * @param outTradeNo
	 *            订单号(唯一)，32字符以内。
	 * @param goodsName
	 *            商品名
	 * @param price
	 *            价格。1代表一元，0.01代表一分。
	 * @param QrBaseCallBack
	 *            回调函数
	 */
	public void onPay(Context context, String outTradeNo, String goodsName,
			String price, QrBaseCallBack QrBaseCallBack) {
		// TODO Auto-generated method stub
		this.context = context;
		// 订单号，必不可少
		NotifyUrl.setOutTradeNo(context, outTradeNo);
		// 商品名，价格
		WeixinManager.getInstance().pay(goodsName, price);

		this.mQrBaseCallBack = QrBaseCallBack;
		isCancel = false;
		// 统一下单
		GetPrepayIdTask getPrepayId = new GetPrepayIdTask();
		getPrepayId.execute();

	}

	/**
	 * 取消支付
	 */
	public void onCancel() {
		isCancel = true;
	}

	// 1.统一下单，获取预支付订单
	private class GetPrepayIdTask extends
			AsyncTask<Void, Void, GetPrepayIdResult> {

		@Override
		protected void onPostExecute(GetPrepayIdResult result) {

			if (result.localRetCode == LocalRetCode.ERR_OK) {
				// 下单成功
				mQrBaseCallBack.onSuccess(code_url, bitmap);
				// 轮询订单结果
				GetRradeStateTask getRradeStateTask = new GetRradeStateTask();
				getRradeStateTask.execute();

			} else {
				mQrBaseCallBack.onFailure("统一下单失败");
			}

		}

		@Override
		protected GetPrepayIdResult doInBackground(Void... params) {
			String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";// 统一下单，预支付订单
			String entity = paramUtil.genProductArgs_Unifiedorder(context,
					"NATIVE");
			try {
				entity = new String(entity.getBytes(), "ISO8859-1");// 微信服务器是ISO8859-1的格式。
			} catch (UnsupportedEncodingException e) {
			}
			GetPrepayIdResult result = new GetPrepayIdResult();

			String content = Util.httpPost(url, entity);
			// Log.e("test", "预支付订单信息" + content);
			if (content == null || content.length() == 0) {
				result.localRetCode = LocalRetCode.ERR_HTTP;
				return result;
			}
			result.parseFrom(content);// 对预下单数据进行解析
			return result;
		}
	}

	// 2.解析预下单数据
	private class GetPrepayIdResult {

		public LocalRetCode localRetCode = LocalRetCode.ERR_OTHER;

		public void parseFrom(String content) {
			if (content == null || content.length() <= 0) {
				localRetCode = LocalRetCode.ERR_JSON;
				return;
			}
			try {
				List<String> list = new ArrayList<String>();
				list.add("code_url");
				Map<String, String> map = paramUtil.xmlPull(content, list,
						"UTF-8");
				if (map != null && map.containsKey("code_url")) {
					// 获取二维码链接，并生成二维码位图
					code_url = map.get("code_url");
					if (code_url != null && !code_url.equals("")) {
						try {
							URL codeUrl = new URL(
									"http://pan.baidu.com/share/qrcode?w=300&h=300&url="
											+ code_url);
							InputStream inputstream = codeUrl.openStream();
							bitmap = BitmapFactory.decodeStream(inputstream);
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
							Log.e("test", "网络二维码图片加载失败" + e.getMessage());
						}
					}
					localRetCode = LocalRetCode.ERR_OK;
				} else {
					localRetCode = LocalRetCode.ERR_JSON;
				}

			} catch (Exception e) {
				localRetCode = LocalRetCode.ERR_JSON;
			}
		}
	}

	// 3.订单查询--轮询
	private class GetRradeStateTask extends
			AsyncTask<Void, Void, GetOrderResult> {
		public Boolean ispPlling = false;// 是否轮询
		public Boolean isSUCCESS = false;// 是否支付成功

		@Override
		protected void onPostExecute(GetOrderResult result) {
			// TODO Auto-generated method stub
			if (result.localRetCode == LocalRetCode.ERR_OK
					&& result.trade_state != null) {

				if (result.trade_state.equals("SUCCESS")) {
					ispPlling = false;
					isSUCCESS = true;
				} else if (result.trade_state.equals("NOTPAY")) {
					// 未支付(一般大多数都是处于该状态,即使有用户扫描，但只要没支付成功，一般都处于该状态。)
					ispPlling = true;
					Log.e("test", "等待支付中。。。");
				} else if (result.trade_state.equals("USERPAYING")) {
					// 用户支付中(输入密码支付后的极短时间。该状态很少很少,基本捕捉不到)
					ispPlling = true;
				} else {
					// 其他状态都为支付失败
					ispPlling = false;
				}
				// if (result.trade_state.equals("REFUND")) {
				// 转入退款
				// Log.e("test", "转入退款");
				// }
				// if (result.trade_state.equals("CLOSED")) {
				// 已关闭
				// Log.e("test", "已关闭");
				// }
				// if (result.trade_state.equals("REVOKED")) {
				// 已撤销（刷卡支付）
				// Log.e("test", "已撤销");
				// }
				// if (result.trade_state.equals("PAYERROR")) {
				// 支付失败(其他原因，如银行返回失败)
				// Log.e("test", "支付失败");
				// }
			} else {
				Log.e("test", "订单查询失败");
			}
			if (ispPlling) {
				// 轮询
				if (!isCancel) {
					GetRradeStateTask getRradeStateTask = new GetRradeStateTask();
					getRradeStateTask.execute();
				} else {
					Log.e("test", "轮询取消");
				}
			} else {
				if (isSUCCESS) {
					// 支付成功
					mQrBaseCallBack.onPaySuccess();
					;
				} else {
					// 支付失败
					mQrBaseCallBack.onFailure("支付失败");
				}
			}
		}

		@Override
		protected GetOrderResult doInBackground(Void... params) {
			// TODO Auto-generated method stub
			String url = "https://api.mch.weixin.qq.com/pay/orderquery";// 查询订单
			String entity = paramUtil.genProductArgs_Query(context);
			try {
				entity = new String(entity.getBytes(), "ISO8859-1");// 微信服务器是ISO8859-1的格式。
			} catch (UnsupportedEncodingException e) {
			}
			String content = Util.httpPost(url, entity);
			// Log.e("test", "订单查询数据"+content);
			GetOrderResult result = new GetOrderResult();
			if (content == null || content.length() == 0) {
				result.localRetCode = LocalRetCode.ERR_HTTP;
				return result;
			}
			result.parseFrom(content);
			return result;
		}
	}

	// 4.解析订单查询数据
	private class GetOrderResult {
		public LocalRetCode localRetCode = LocalRetCode.ERR_OTHER;
		public String trade_state = null;

		public String parseFrom(String content) {

			if (content == null || content.length() <= 0) {
				localRetCode = LocalRetCode.ERR_JSON;
				return trade_state;
			}
			try {
				List<String> list = new ArrayList<String>();
				list.add("trade_state");
				Map<String, String> map = paramUtil.xmlPull(content, list,
						"UTF-8");
				if (map != null && map.containsKey("trade_state")) {
					trade_state = map.get("trade_state");
					localRetCode = LocalRetCode.ERR_OK;
				} else {
					localRetCode = LocalRetCode.ERR_JSON;
				}

			} catch (Exception e) {
				localRetCode = LocalRetCode.ERR_JSON;
			}
			return trade_state;
		}
	}
}
